/*************************************************************************
Title:    testing output to a HD44780 based LCD display.
Author:   Peter Fleury  <pfleury@gmx.ch>  http://jump.to/fleury
File:     $Id: test_lcd.c,v 1.6 2004/12/10 13:53:59 peter Exp $
Software: AVR-GCC 3.3
Hardware: HD44780 compatible LCD text display
          ATS90S8515/ATmega if memory-mapped LCD interface is used
          any AVR with 7 free I/O pins if 4-bit IO port mode is used
**************************************************************************/

#include <stdlib.h>
#include <avr/io.h>
#include "I2C.h"
#include "ds1307.h"
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include "lcd.h"
#include "uart.h"

#define pushButton1  0x0E
#define pushButton2	 0x0D
#define pushButton3  0x0B
#define pushButton4  0x07

/* define CPU frequency in Mhz here if not defined in Makefile */
// #ifndef F_CPU
#define F_CPU 8000000UL
// #endif

/* 9600 baud */
#define UART_BAUD_RATE      38400

/*debounce Variables*/
#define DEBOUNCE_TIME		0.3
#define SAMPLE_FREQUENCY	10
#define MAXIMUM			(DEBOUNCE_TIME * SAMPLE_FREQUENCY)

uint16_t key_count;
static char str[20];
static char Time[12];	//hh:mm:ss AM/PM
/*
** constant definitions
*/
static const PROGMEM unsigned char copyRightChar[] =
{
	0x07, 0x08, 0x13, 0x14, 0x14, 0x13, 0x08, 0x07,
	0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00
};


void timer_init(){
	
	TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode 

    TIMSK |= (1 << OCIE1A); // Enable CTC interrupt 

}

char checkKeys();

int main(void)
{

	char buffer[7];
    int  num=134;
    unsigned char i;
    
    key_count = 0;
    // DDRD &=~ (1 << PD2);        /* Pin PD2 input              */
    // PORTD |= (1 << PD2);        /* Pin PD2 pull-up enabled    */

	DDRB |= 0x0F;
	DDRC &= ~(1<<PC3);
	
	/*
     *  Initialize UART library, pass baudrate and AVR cpu clock
     *  with the macro 
     *  UART_BAUD_SELECT() (normal speed mode )
     *  or 
     *  UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode)
	*/
    
	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

	/* initialize display, cursor off */
    lcd_init(LCD_DISP_ON);
	
	/*initialise the Timer*/
	timer_init();
	
	/*
     * now enable interrupt
    */
    
	sei();
	
	/*
	*The match compare value
	*This value specifies the number of timer 'ticks'
	*before an interrupt occurs
	*The ISR is used to update the display at regular intervals.
	*A good way to avoid long delay loops that waste the processor time!!
	*/
	OCR1A   = 300;
	
    TCCR1B |= ((1 << CS10) | (1 << CS12)); // Start timer at Fcpu/1024
	
	uart_puts("String stored in SRAM\n");
	
	uart_puts_P("String stored in FLASH\n");
	
	I2CInit();
	
	uint8_t temp;
	DS1307Read(0x00,&temp);
	
	//Clear CH bit of RTC
	#define CH 7
	
	//Clear CH Bit
	temp&=(~(1<<CH));

	DS1307Write(0x00,temp);

	//Set 12 Hour Mode
	DS1307Read(0x02,&temp);

	//Set 12Hour BIT
	temp|=(0b01000000);

	//Write Back to DS1307
	DS1307Write(0x02,temp);
	
	//Now Read and format time
	uint8_t data;
	
	
	lcd_clrscr();
	//lcd_puts("Stop SOPA/PIPA\n");
	int dummy = 0;
    for (;;) {                           /* loop forever */
        /* 
         * Test 1:  write text to display
         */
		// PORTB ^= (1 << PB4);
        /* clear display and home cursor */
        // lcd_clrscr();
        
        /* put string to display (line 1) with linefeed */
		// uart_puts("str\n");
		
		DS1307Read(0x00,&data);
		Time[8]='\0';
		Time[7]=48+(data & 0b00001111);
		Time[6]=48+((data & 0b01110000)>>4);
		Time[5]=':';
	
		DS1307Read(0x01,&data);
	
		Time[4]=48+(data & 0b00001111);
		Time[3]=48+((data & 0b01110000)>>4);
		Time[2]=':';
	
		DS1307Read(0x02,&data);
	
		Time[1]=48+(data & 0b00001111);
		Time[0]=48+((data & 0b00010000)>>4);
		
		dummy = uart_getc();
		if(dummy == 'c'){
			//uart_putc(dummy);
			uart_puts("\nHello!");
		}
		checkKeys();
    }
	return 0;
}
/*
*This is the Lcd Refresh Function
*Put all the stuff That is to be refreshed at regular intervals
*in this ISR
*/
ISR(TIMER1_COMPA_vect) 
{ 
   // uart_puts("isr\n");
   PORTC ^=(1 << PC3); 
   lcd_gotoxy(0,1);
   lcd_puts(Time);
}

/*This returns the status of the Keys
*The debouncing is done in this functions
*/


char checkKeys()
{
	unsigned char i;
	unsigned char button;
  
	DDRB  = 0xf0;  //keyboard port
	// if(PINB != 0x0f){
	for(i=0; i<4; i++){

		uint8_t input;       /* 0 or 1 depending on the input signal */
		uint8_t integrator;  /* Will range from 0 to the specified MAXIMUM */
		uint8_t output;      /* Cleaned-up version of the input signal */

		input = (PINB & 0x0f);

		if (input == 0){
			if (integrator > 0)
				integrator--;
		}
		else if (integrator < MAXIMUM)
			integrator++;

		if (integrator == 0)
			output = 0;
		else if (integrator >= MAXIMUM){
			key_count =0;
			output = 1;
			integrator = MAXIMUM;  /* defensive code if integrator got corrupted */
		}
		
		if (output){	
			switch(PINB & 0x0f)
			{
				case(pushButton1): 	lcd_clrscr();
									// lcd_gotoxy(0,0);
									// uart_puts("pb1\n");
									key_count++;
									button = 1;
									// MUp()
									// lcd_puts("Set Time  ");
								 break;
								 
				case(pushButton2):	lcd_clrscr();
									// lcd_gotoxy(0,0);
									// uart_puts("pb2\n");
									key_count++;
									button = 2;
									// MoveDown();
									// lcd_puts("Set Alarm ");
								 break;
								 
				case(pushButton3):  lcd_clrscr();
									lcd_gotoxy(0,0);
									// uart_puts("pb3\n");
									key_count++;
									button = 3;
									// Back
									// lcd_puts("Set BL TO ");
								 break;
								 
				case(pushButton4): 	lcd_clrscr();
									lcd_gotoxy(0,0);
									// uart_puts("pb4\n");
									button = 4;
									key_count++;
									// lcd_puts("4");
								 break;
								 
			  default: 	  		 	//lcd_clrscr();
									// lcd_gotoxy(0,0);
									// lcd_puts("     ");
								 break;
			}//end of switch()
		
		// sprintf(str,"\ncount %d",key_count);
		// uart_puts(str);
		}
	}
return button;	
}
